<?php

namespace app\api\controller;

use app\admin\model\Alipay;
use app\admin\model\Cart;
use app\admin\model\Category;
use app\admin\model\Coupon;
use app\admin\model\Goods;
use app\admin\model\GoodsAttr;
use app\admin\model\OilOrder;
use app\admin\model\OilOrderRefund;
use app\admin\model\Order;
use app\admin\model\OrderGoods;
use app\admin\model\OrderGoodsRefund;
use app\admin\model\OrderGoodsRefund2;
use app\admin\model\Station;
use app\admin\model\UserAddress;
use app\admin\model\UserCard;
use app\admin\model\UserCoupon;
use app\admin\model\UserMoneyLog;
use app\admin\model\Wechat;
use app\common\controller\Frontend;
use Exception;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\db\Query;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\Validate;

class Store extends Frontend
{
    protected $noNeedLogin = ['checkIn', 'logout'];

    protected $noNeedPermission = ['index'];

    public function initialize()
    {
        parent::initialize();
    }

    /**
     * 加入购物车
     * @param Cart $cart
     * @param Goods $goods
     * @param GoodsAttr $attr
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function addCart(Cart $cart, Goods $goods, GoodsAttr $attr)
    {
        $param = $this->request->post();
        $userId = $this->auth->getUserId();

        $validate = Validate::rule([
            'goods_id' => 'require|integer|gt:0',
            'attr_id' => 'require|integer|gt:0',
            'num' => 'require|integer|gt:0',
        ])->message([
            'goods_id' => '商品参数错误',
            'attr_id' => '属性参数错误',
            'num' => '数量参数错误',
        ]);;
        if (!$validate->check($param)) $this->error($validate->getError());
        // 商品是否存在
        if ($goods->where(['id' => $param['goods_id'], 'switch' => 1])->count() == 0) {
            $this->error('商品不存在或已下架');
        }
        // 属性是否存在
        if ($attr->where(['id' => $param['attr_id'], 'goods_id' => $param['goods_id']])->count() == 0) {
            $this->error('属性不存在');
        }
        // 合并未支付的同商品数据
        $cartList = $cart->where(['user_id' => $userId, 'is_pay' => 0])->select();
        $newItems = [];
        Db::startTrans();
        try {
            foreach ($cartList as $item) {
                $item->delete();
                $newItems[$item['goods_id'] . '-' . $item['attr_id']] = [
                    'user_id' => $userId,
                    'goods_id' => $item['goods_id'],
                    'attr_id' => $item['attr_id'],
                    'num' => ($newItems[$item['goods_id'] . '-' . $item['attr_id']]['num'] ?? 0) + $item['num'],
                ];
            }
            $cart->saveAll($newItems);
            if ((int)($param['buy_now'] ?? 0) == 1) {
                $cart->save([
                    'user_id' => $userId,
                    'goods_id' => $param['goods_id'],
                    'attr_id' => $param['attr_id'],
                    'num' => $param['num'],
                    'buy_now' => 1,
                ]);

                $cart = $cart
                    ->where([
                        'id' => $cart['id'],
                    ])
                    ->with(['goods', 'attr'])
                    ->hidden(array_merge(['pay_time', 'is_pay', 'user_id'], $this->hidden))
                    ->find();
                $cart['goods']['slider_images'] = full_array_url($cart['goods']['slider_images']);
                $cart['attr']['image'] = full_url($cart['attr']['image']);

            } else {
                // 购物车是否已存在该数据
                $cartData = $cart->where([
                    'user_id' => $userId,
                    'goods_id' => $param['goods_id'],
                    'attr_id' => $param['attr_id'],
                    'is_pay' => 0,
                ])->find();
                if ($cartData) {
                    $cart = $cartData;
                }
                $cart->save([
                    'user_id' => $this->auth->getUserId(),
                    'goods_id' => $param['goods_id'],
                    'attr_id' => $param['attr_id'],
                    'num' => $cart['num'] + $param['num'],
                ]);
            }
            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        $this->success('操作成功', $cart);
    }

    public function cartGoodsNum(Cart $cart)
    {
        $data = $this->request->post();
        $cartInfo = $cart->where('id', $data['cart_id'])->find();
        if ($cartInfo['user_id'] != $this->auth->getUserId()) $this->error('当前购物车数据不属于你');
        $data['num'] = (int)($data['num'] ?? 0);
        if ($data['num'] <= 0) {
            $this->error('数量必须大于0');
        }
        $cartInfo->num = $data['num'];
        $cartInfo->save();
        $this->success('操作成功');
    }

    /**
     * @param $ids
     * @param Cart $cart
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function checkedCart($ids, Cart $cart)
    {
        $ids = explode(',', $ids);
        $userId = $this->auth->getUserId();
        $cart
            ->where([
                'user_id' => $userId,
                'is_pay' => 0,
            ])
            ->update(['checked' => 0]);
        $cart
            ->where([
                'user_id' => $userId,
                'is_pay' => 0,
            ])
            ->whereIn('id', $ids)
            ->update(['checked' => 1]);
        $cartInfo = $cart
            ->where([
                'user_id' => $userId,
                'is_pay' => 0,
            ])
            ->whereIn('id', $ids)
            ->with(['goods', 'attr'])
            ->hidden(array_merge(['pay_time', 'is_pay', 'user_id'], $this->hidden))
            ->select();
        $price = 0;
        foreach ($cartInfo as $info) {
            if (isset($info['goods']) && isset($info['goods']['price'])) {
                $price += $info['num'] * $info['goods']['price'];
            }
        }
        $this->success('操作成功', ['price' => sprintf('%.2f', $price)]);
    }

    /**
     * @param $id
     * @param Cart $cart
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function deleteCart($id, Cart $cart)
    {
        $userId = $this->auth->getUserId();
        if (is_array($id)) {
            $ids = $id;
        } else {
            $ids = json_decode($id, true);
        }
        $addressData = $cart->where(['user_id' => $userId])->whereIn('id', $ids)->select();
        if ($addressData->isEmpty()) {
            $this->error('数据不存在');
        }
        $addressData->delete();
        $this->success('删除成功');
    }

    /**
     * @param Cart $cart
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getCart(Cart $cart)
    {
        $userId = $this->auth->getUserId();
        $cartInfo = $cart
            ->where([
                'user_id' => $userId,
                'is_pay' => 0,
                'buy_now' => 0,
            ])
            ->with(['goods', 'attr'])
            ->hidden(array_merge(['pay_time', 'is_pay', 'user_id'], $this->hidden))
            ->select()
            ->each(function ($item) {
                if (isset($item['goods']) && isset($item['goods']['slider_images'])) {
                    $item['goods']['slider_images'] = full_array_url($item['goods']['slider_images']);
                }
                $item['attr']['image'] = full_url($item['attr']['image']);
                return $item;
            });

        $price = 0;
        foreach ($cartInfo as $info) {
            if ($info['checked'] == 1 && isset($info['attr']) && isset($info['attr']['price'])) {
                $price += $info['num'] * $info['attr']['price'];
            }
        }
        $this->success('获取成功', compact('cartInfo', 'price'));
    }

    /**
     * @param Order $order
     * @param UserAddress $userAddress
     * @param Cart $userCart
     * @param UserCard $userCard
     * @param OrderGoods $orderGoods
     * @param UserCoupon $userCoupon
     * @param Category $category
     * @param int $create
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function createOrder(
        Order $order,
        UserAddress $userAddress,
        Cart $userCart,
        UserCard $userCard,
        OrderGoods $orderGoods,
        UserCoupon $userCoupon,
        Category $category,
        int $create = 1
    )
    {
        $param = $this->request->post(['address_id', 'cart_ids', 'remark', 'coupon_id', 'channel', 'score', 'payway']);
        $payway = trim($param['payway']);
        $userInfo = $this->auth->getUserInfo();
        if ($payway == 'wechat' && !$userInfo['routine_openid']) $this->error('暂未微信授权');
        $param['score'] = (int)$param['score'];
        $param['channel'] = (int)$param['channel'];
        if (!in_array($param['channel'], [0, 1])) $this->error('调用平台不合法');
        $address = $userAddress->where(['user_id' => $userInfo['id'], 'id' => (int)($param['address_id']??0)])->find();
        if (!$address) $this->error('收货地址不存在');
        if (is_string($param['cart_ids'])) {
            $param['cart_ids'] = json_decode($param['cart_ids'], true);
        }

        if (!$param['cart_ids']) $this->error('购物车数据错误');
        try {
            $cart = $userCart
                ->with(['goods', 'attr'])
                ->whereIn('id', $param['cart_ids'])
                ->where('is_pay', 0)
                ->select()
                ->each(function ($item) {
                    if (!$item['goods'] || !$item['attr']) {
                        throw new ValidateException('部分商品已失效');
                    }
                });
            if ($cart->isEmpty()) throw new ValidateException('购物车数据不存在');
            $totalPrice = 0;
            $postPrice = [];
            $cartGoodsIds = [];
            foreach ($cart as $v) {
                $totalPrice += (float)bcmul($v['attr']['price'], $v['num'], 2);
                $postPrice[] = (float)$v['goods']['post_price'];
                $cartGoodsIds[] = $v['goods_id'];
            }
            $discount = 0;
            if ($userInfo['level'] > 0 && $totalPrice > 0) {
                $card = $userCard->where(['switch' => 1, 'id' => $userInfo['level']])->find();
                if ($card['discount'] > 0 && $card['discount'] <= 1) {
                    $discount = bcsub($totalPrice, bcmul($totalPrice, $card['discount'], 2));
                }
            }

            $order->startTrans();
            $order->user_id = $userInfo['id'];
            $order->order_sn = $order->getOrderSn();
            $order->username = $address['username'];
            $order->channel = $param['channel'];
            $order->mobile = $address['mobile'];
            $order->address = $address['address'];
            $order->total_price = (float)$totalPrice;
            $order->post_price = max($postPrice);
            $order->discount = (float)$discount;
            // 扣除会员优惠
            $order->pay_price = bcsub($totalPrice, $discount, 2);
            $order->coupon_price = 0;

            $userCouponId = (int)$param['coupon_id'];
            if ($userCouponId > 0) {
                $coupon = $userCoupon->with(['coupon'])->where(['id' => $userCouponId])->find();
                if (!$coupon) {
                    throw new ValidateException('优惠券不存在');
                }
                if (!$coupon['coupon']) {
                    throw new ValidateException('优惠券不存在');
                }
                if ($coupon['updatetime'] > 0) {
                    throw new ValidateException('优惠券已使用');
                }
                if ($coupon['coupon']['goods_ids'] || $coupon['coupon']['category_ids']) {
                    $goodsIds = $coupon['coupon']['goods_ids'];
                    $categoryIds = $category->getTree($coupon['coupon']['category_ids']);
                    $goodsIds = array_merge($goodsIds, $categoryIds);
                    foreach ($cartGoodsIds as $gid) {
                        if (!in_array($gid, $goodsIds)) {
                            throw new ValidateException('有不支持优惠券的商品，请单独购买');
                        }
                    }
                }
                $order->coupon_id = $userCouponId;
                $order->coupon_price = (float)min($coupon['coupon']['price'], $order->pay_price);
                // 扣除优惠券优惠
                $order->pay_price = bcsub($order->pay_price, $order->coupon_price, 2);
            }

            // 加上邮费
            $order->pay_price = bcadd($order->pay_price, $order->post_price, 2);
            $order->pay_price = (float)(max($order->pay_price, 0));
            $order->pay_type = $payway;
            $order->pay_time = 0;
            $order->remark = $param['remark'];
            $order->state = 0;
            if ($create == 0) {
                $order->save();
            }

            $goods = [];
            $score = 0;
            foreach ($cart as $v) {
                if ($v['goods']['use_score'] > 0) {
                    $score += $v['goods']['use_score'];
                }
                $goods[] = [
                    'order_id' => $order->id ?? 0,
                    'goods_id' => $v['goods_id'],
                    'goods_image' => $v['attr']['image'] ?: ($v['goods']['slider_images'] ? $v['goods']['slider_images'][0] : ''),
                    'goods_name' => $v['goods']['goods_name'],
                    'attr_name' => $v['attr']['key'],
                    'price' => $v['attr']['price'],
                    'old_price' => $v['goods']['old_price'],
                    'total' => $v['num'],
                ];
                // 减少库存
                $v->goods->stock -= $v['num'];
                if ($v->goods->stock < 0) throw new ValidateException('[' . $v->goods->goods_name . ']库存不足');
                $v->goods->save();
                $v->attr->stock -= $v['num'];
                if ($v->attr->stock < 0) throw new ValidateException('[' . $v->goods->goods_name . ':' . $v->attr->key . ']库存不足');
                $v->attr->save();
            }
            // 抵扣积分
            if ($param['score'] > 0) {
                $order->use_score = min($userInfo['score'], $score, $param['score']);
            } elseif ($param['score'] == -1) {
                $order->use_score = min($userInfo['score'], $score);
            }
            $score2money = (float)get_sys_config('score2money');
            if ($score2money > 0 && $order->use_score > 0) {
                $order->score_money = bcdiv($order->use_score, $score2money, 2);
                $order->pay_price -= $order->score_money;
            }
            if ($create == 0) {
                $orderGoods->saveAll($goods);
                // $cart->update(['is_pay' => 1]); // TODO 取消自动支付
                if ($payway == 'wechat') {
                    $wechat = new Wechat();
                    $payment = $wechat->payment('购买商品', $order['order_sn'], $order['pay_price'], $userInfo['routine_openid'], $param['channel'], 0);
                } elseif ($payway == 'alipay') {
                    $wechat = new Alipay();
                    $payment = $wechat->payment('购买商品', $order['order_sn'], $order['pay_price'], $param['channel'], 0);
                } elseif ($payway == 'balance') {
                    if ($this->auth->getUserInfo()['money'] < $order['pay_price']) {
                        throw new ValidateException('余额不足');
                    }
                    UserMoneyLog::create([
                        'user_id' => $this->auth->getUserId(),
                        'money' => -$order['pay_price'],
                        'memo' => '购买商品',
                    ]);

                    (new Order)->paySuccess([
                        'out_trade_no' => $order->order_sn,
                        'transaction_id' => '',
                    ]);
                } else {
                    throw new ValidateException('支付方式错误');
                }
                $order->commit();
            }
        } catch (Exception $e) {
            $order->rollback();
            $this->error($e->getMessage());
        }

        $hidden = ['user_id', 'pay_time', 'createtime', 'updatetime'];
        if ($create == 1) {
            $hidden[] = 'order_sn';
        }
        $this->success('', [
            'payment' => $payment ?? [],
            'orderInfo' => $order->hidden($hidden),
        ]);
    }

    /**
     * @param OilOrder $order
     * @param UserCard $userCard
     * @param Station $stationModel
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public
    function createOilOrder(OilOrder $order, UserCard $userCard, Station $stationModel)
    {
        $param = $this->request->post(['station_id', 'oil_type', 'gun_number', 'price', 'remark', 'channel', 'payway', 'coupon_id']);
        $payway = trim($param['payway']);
        $couponId = (int)$param['coupon_id'];
        $param['price'] = floatval($param['price']);

        $userInfo = $this->auth->getUserInfo();
        if (
            $param['oil_type'] == '柴油' && $userInfo['check'] == 0
        ) {
            $this->error('请先完成实名认证', null, 2);
        }
        if ($payway == 'wechat' && !$userInfo['routine_openid']) {
            $this->error('请先进行授权微信');
        }

        if ($couponId > 0) {
            $userCoupon = UserCoupon::where(['user_id' => $userInfo['id'], 'id' => $couponId])->find();
            if (!$userCoupon || $userCoupon->isEmpty()) $this->error('优惠券不存在');
            if ($userCoupon->updatetime > 0) $this->error('优惠券已被使用');

            $coupon = Coupon::where('id', $userCoupon['coupon_id'])->find();
            if (!$coupon) $this->error('优惠券不存在');

            if ($coupon['can_oil'] == 0) $this->error('优惠券不允许加油使用');
            if ($param['price'] < $coupon['condition']) {
                $this->error('不满足优惠券使用条件');
            }
        }

        $validate = Validate::rule([
            'station_id' => 'require|integer|gt:0',
            'oil_type' => 'require',
            'gun_number' => 'require',
            'price' => 'require|regex:^(?!(0[0-9]{0,}$))[0-9]{1,}[.]{0,}[0-9]{0,}$',
        ])->message([
            'station_id' => '油站参数错误',
            'oil_type' => '油号参数错误',
            'gun_number' => '油枪参数错误',
            'price' => '支付金额参数错误',
        ]);;
        if (!$validate->check($param)) $this->error($validate->getError());

        $param['channel'] = (int)$param['channel'];
        if (!in_array($param['channel'], [0, 1])) $this->error('调用平台不合法');

        $station = $stationModel->where(['switch' => 1, 'id' => $param['station_id']])->find();
        if (!$station) $this->error('加油站不存在');

        try {

            $order->startTrans();
            $order->user_id = $userInfo['id'];
            $order->station_id = $param['station_id'];
            $order->oil_type = $param['oil_type'];
            $order->gun_number = $param['gun_number'];
            $order->coupon_id = $couponId;

            if (isset($coupon)) {
                $couponPrice = $coupon->price;
                $order->coupon_price = $couponPrice;
                $order->pay_price = bcsub($param['price'], $couponPrice, 2);
            } else {
                if ($userInfo['level'] > 0 && $param['price'] > 0) {
                    $card = $userCard->where(['switch' => 1, 'id' => $userInfo['level']])->find();
                    if ($card['discount'] > 0 && $card['discount'] <= 1) {
                        $discount = bcsub($param['price'], bcmul($param['price'], $card['discount'], 2));
                        $order->discount = (float)$discount;
                        $order->pay_price = bcsub($param['price'], $discount, 2);
                    }
                }
            }

            $order->oil_price = $station['price'];
            $order->order_sn = $order->getOrderSn();
            $order->total_price = (float)$param['price'];
            // 扣除会员优惠
            $order->pay_price = (float)($order->pay_price < 0 ? 0 : $order->pay_price);
            $order->pay_time = 0;
            $order->remark = $param['remark'];
            $order->state = 0;
            $order->pay_type = $payway;
            $order->save();
            if (isset($userCoupon)) {
                $userCoupon->update([
                    'updatetime' => time(),
                ], [
                    'id' => $userCoupon->id,
                ]);
            }

            if ($payway == 'wechat') {
                UserMoneyLog::create([
                    'user_id' => $this->auth->getUserId(),
                    'money' => $order['pay_price'],
                    'memo' => '购买商品',
                ]);
                $wechat = new Wechat();
                $payment = $wechat->payment('加油', $order['order_sn'], $order['pay_price'], $userInfo['routine_openid'], $param['channel'], 1);
            } elseif ($payway == 'alipay') {
                $alipay = new Alipay();
                $payment = $alipay->payment('加油', $order['order_sn'], $order['pay_price'], $param['channel'], 0);
            } elseif ($payway == 'balance') {
                if ($this->auth->getUserInfo()['money'] < $order['pay_price']) {
                    throw new ValidateException('余额不足');
                }
                UserMoneyLog::create([
                    'user_id' => $this->auth->getUserId(),
                    'money' => -$order['pay_price'],
                    'memo' => '加油',
                ]);
                (new OilOrder())->paySuccess([
                    'out_trade_no' => $order->order_sn,
                    'transaction_id' => '',
                ]);
            } else {
                throw new ValidateException('支付方式错误');
            }
            $order->commit();
        } catch (Exception $e) {
            $order->rollback();
            $this->error($e->getMessage());
        }

        $hidden = ['user_id', 'pay_time', 'createtime', 'updatetime'];
        $this->success('', [
            'payment' => $payment ?? [],
            'orderInfo' => $order->hidden($hidden),
        ]);
    }

    /**
     * @param Order $order
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public
    function getOrderList(Order $order)
    {
        $page = (int)$this->request->get('page', 1);
        $page = $page <= 0 ? 1 : $page;
        $limit = (int)$this->request->get('limit', 1);
        $limit = $limit <= 0 ? 10 : $limit;
        $status = (int)$this->request->get('status', 1);
        // 0=全部，1=待付款，2=待发货，3=已发货，4=已完成，5=退换货
        $status = max($status, 0);
        $list = $order
            ->with(['orderGoods'])
            ->page($page, $limit)
            ->where('user_id', $this->auth->getUserId())
            ->when($status > 0, function (Query $query) use ($status) {
                if ($status == 1) {
                    $query->where('state', 0);
                } elseif ($status == 2) {
                    $query->where('state', 1);
                } elseif ($status == 3) {
                    $query->where('state', 2);
                } elseif ($status == 4) {
                    $query->where('state', 3);
                } elseif ($status == 5) {
                    $query->whereIn('state', [4, 5]);
                }
            })
            ->order('id desc')
            ->hidden(['commission', 'updatetime', 'delete_time'])
            ->select()
            ->each(function ($item) use ($order) {
                $item['state_txt'] = $order->getStateTxt($item['state']);
                foreach ($item['orderGoods'] as $k => $v) {
                    $item['orderGoods'][$k]['goods_image'] = full_url($item['orderGoods'][$k]['goods_image']);
                }
                return $item;
            });
        $this->success('', $list);
    }

    /**
     * @param OilOrder $order
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public
    function getOilOrderList(OilOrder $order)
    {
        $page = (int)$this->request->get('page', 1);
        $page = $page <= 0 ? 1 : $page;
        $limit = (int)$this->request->get('limit', 10);
        $limit = $limit <= 0 ? 10 : $limit;
        $status = (int)$this->request->get('status', 1);
        // 0=全部，1=待支付，2=已支付，3=退款中，4=已退款
        $status = max($status, 0);
        $list = $order
            ->with(['station'])
            ->page($page, $limit)
            ->when($status > 0, function (Query $query) use ($status) {
                if ($status == 1) {
                    $query->where('state', 0);
                } elseif ($status == 2) {
                    $query->where('state', 1);
                } elseif ($status == 3) {
                    $query->where('state', 2);
                } elseif ($status == 4) {
                    $query->where('state', 3);
                } elseif ($status == 5) {
                    $query->where('state', 4);
                }
            })
            ->where('user_id', $this->auth->getUserId())
            ->hidden(['commission', 'updatetime', 'delete_time'])
            ->order('id desc')
            ->select()
            ->each(function ($item) use ($order) {
                $item['state_txt'] = $order->getOilStateTxt($item['state']);
                return $item;
            });
        $this->success('', $list);
    }

    /**
     * @param Order $order
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public
    function cancelOrder(Order $order)
    {
        $orderSn = $this->request->post('order_sn', '');
        $orderSn = trim($orderSn);
        $orderInfo = $order->where('order_sn', $orderSn)->find();
        if (!$orderInfo || $orderInfo->isEmpty()) {
            $this->error('订单不存在');
        }
        if ($orderInfo['state'] != 0) {
            $this->error('当前状态不允许取消订单');
        }
        $orderInfo->state = 7;
        $orderInfo->save();
        $this->success('成功取消订单');
    }

    /**
     * @param Order $order
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public
    function rePay(Order $order)
    {
        $orderSn = $this->request->get('order_sn', '');
        $orderSn = trim($orderSn);
        $orderInfo = $order->where('order_sn', $orderSn)->find();
        if (!$orderInfo || $orderInfo->isEmpty()) {
            $this->error('订单不存在');
        }
        if ($orderInfo['state'] != 0) {
            $this->error('当前状态不允许支付');
        }

        try {
            $wechat = new Wechat();
            $userInfo = $this->auth->getUserInfo();
            $payment = $wechat->payment('购买商品', $orderInfo['order_sn'], $orderInfo['pay_price'], $userInfo['routine_openid'], $orderInfo['channel'], 0);
        } catch (Exception $e) {
            $this->error($e->getMessage());
        }
        $this->success('', $payment ?? []);
    }

    /**
     * @param OrderGoods $orderGoods
     * @param OrderGoodsRefund $refund
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public
    function refundOrder(OrderGoods $orderGoods, OrderGoodsRefund $refund)
    {
        $params = $this->request->post();
        $data = [
            'refund_sn' => $refund->getOrderSn(),
            'order_goods_id' => $params['order_goods_id'] ?? 0,
            'check' => 0,
        ];
        if ($params['refund_type'] == 3) {
            if (!isset($params['change_attr']) || !$params['change_attr']) {
                $this->error('请选择换货规格');
            }
            if (!isset($params['receive_username']) || !$params['receive_username']) {
                $this->error('收货人不能为空');
            }
            if (!isset($params['receive_mobile']) || !$params['receive_mobile']) {
                $this->error('收货人联系方式不能为空');
            }
            if (!isset($params['receive_address']) || !$params['receive_address']) {
                $this->error('收货地址不能为空');
            }
            $data['change_attr'] = $params['change_attr'];
            $data['receive_username'] = $params['receive_username'];
            $data['receive_mobile'] = $params['receive_mobile'];
            $data['receive_address'] = $params['receive_address'];
        }
        $data['images'] = is_string($params['photos']) ? json_decode(htmlspecialchars_decode($params['photos']), true) : $params['photos'];
        $data['refund_remark'] = $params['remark'];
        $data['images'] = implode(',', $data['images']);
        $goods = $orderGoods->where('id', $params['order_goods_id'])->with(['orderInfo'])->find();
        if (!$goods) $this->error('数据不存在');
        if ($goods->orderInfo->pay_time <= 0) $this->error('订单未支付，不允许退款');
        $refunded = $refund
            ->where([
                'order_goods_id' => $params['order_goods_id'],
            ])
            ->whereIn('state', [1, 2, 3])
            ->count();
        if ($refunded > 0) $this->error('已售后');
        if ($params['price'] > ($goods->price * $goods->total) - $goods->orderInfo->post_price) {
            $this->error('超过可退款金额');
        }
        $data['refund_reason'] = $params['reason'];
        $data['goods_state'] = $params['goods_state'];
        $data['refund_type'] = $params['refund_type'];
        $data['refund_price'] = $params['price'];
        $data['state'] = $params['refund_type'];
        Db::transaction(function () use ($refund, $goods, $data) {
            $refund->save($data);
            $goods->orderInfo->state = 4;
            $goods->orderInfo->save();
        });
        $this->success('申请成功，等待审核', ['order_sn' => $data['refund_sn']]);
    }

    /**
     * @param OrderGoods $orderGoods
     * @param OrderGoodsRefund2 $refund
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public
    function refund(OrderGoods $orderGoods, OrderGoodsRefund2 $refund)
    {
        $params = $this->request->post();
        $data = [
            'refund_sn' => $refund->getOrderSn(),
        ];
        if (is_array($params['order_goods_id'])) {
            $orderGoodsIds = $params['order_goods_id'];
        } else {
            $orderGoodsIds = json_decode($params['order_goods_id'], true);
        }
        if (count($orderGoodsIds) == 0) $this->error('参数错误');
        Db::startTrans();
        try {
            foreach ($orderGoodsIds as $orderGoodsId) {
                $data['order_goods_id'] = $orderGoodsId;
                $data['images'] = is_string($params['images']) ? json_decode(htmlspecialchars_decode($params['images']), true) : $params['images'];
                $data['images'] = implode(',', $data['images']);
                $data['order_status'] = $params['order_status'];
                $data['remark'] = $params['remark'];
                $goods = $orderGoods->where('id', $orderGoodsId)->with(['orderInfo'])->find();
                if (!$goods) throw new ValidateException('数据不存在');
                if ($goods->orderInfo->pay_time <= 0) throw new ValidateException('订单未支付，不允许退款');
                $refunded = $refund
                    ->where([
                        'order_goods_id' => $orderGoodsId,
                    ])
                    ->whereIn('state', [0, 1, 2])
                    ->count();
                if ($refunded > 0) throw new ValidateException('已售后');
                if ($params['price'] > $goods->orderInfo->pay_price) {
                    throw new ValidateException('超过可退款金额');
                }
                $data['reason'] = $params['reason'];
                $data['state'] = 0;
                $data['refund_type'] = 0;
                $data['price'] = $params['price'];
                $refund->create($data);
                $goods->orderInfo->state = 4;
                $goods->orderInfo->save();
            }
            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        $this->success('申请成功，等待审核', ['order_sn' => $data['refund_sn']]);
    }

    /**
     * @param OilOrderRefund $refund
     * @param OilOrder $oilOrder
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public
    function refundOil(OilOrderRefund $refund, OilOrder $oilOrder)
    {
        $params = $this->request->post();
        $data = [
            'refund_sn' => $refund->getOrderSn(),
        ];
        $data['reason'] = $params['reason'];
        $data['price'] = $params['price'];
        $data['images'] = is_string($params['images']) ? json_decode(htmlspecialchars_decode($params['images']), true) : $params['images'];
        $data['images'] = implode(',', $data['images']);
        $data['remark'] = $params['remark'];
        $data['order_id'] = $params['order_id'];
        $order = $oilOrder->where('id', $params['order_id'])->find();
        $refunded = $refund
            ->where([
                'order_id' => $order->id,
            ])
            ->whereIn('state', [0, 1, 2])
            ->count();
        if ($refunded > 0) $this->error('已售后');
        if ($params['price'] > $order->pay_price) {
            $this->error('超过可退款金额');
        }
        $data['state'] = 0;
        $data['refund_type'] = 0;
        Db::transaction(function () use ($refund, $order, $data) {
            $refund->save($data);
            $order->state = 4;
            $order->save();
        });
        $this->success('申请成功，等待审核', ['order_sn' => $data['refund_sn']]);
    }

    public
    function changeGoods(OrderGoods $orderGoods, OrderGoodsRefund2 $refund)
    {
        $params = $this->request->post();
        if (!$params['username']) $this->error('请填写收货人');
        if (!$params['mobile']) $this->error('请填写收货人手机号');
        if (!$params['address']) $this->error('请填写详细地址');
        $data = [
            'refund_sn' => $refund->getOrderSn(),
            'order_goods_id' => $params['order_goods_id'] ?? 0,
            'username' => $params['username'] ?? '',
            'mobile' => $params['mobile'] ?? '',
            'address' => $params['address'] ?? '',
        ];
        $data['images'] = is_string($params['images']) ? json_decode(htmlspecialchars_decode($params['images']), true) : $params['images'];
        $data['images'] = implode(',', $data['images']);
        $data['remark'] = $params['remark'];
        $data['reason'] = $params['reason'];
        $data['change_attr'] = $params['change_attr'];
        $data['order_status'] = 1;
        $data['state'] = 0;
        $goods = $orderGoods->where('id', $params['order_goods_id'])->with(['orderInfo'])->find();
        if (!$goods) $this->error('数据不存在');
        if ($goods->orderInfo->pay_time <= 0) $this->error('订单未支付，不允许换货');
        $refunded = $refund
            ->where([
                'order_goods_id' => $params['order_goods_id'],
            ])
            ->whereIn('state', [0, 1, 2])
            ->count();
        if ($refunded > 0) $this->error('已售后');
        $data['refund_type'] = 1;
        Db::transaction(function () use ($refund, $goods, $data) {
            $refund->save($data);
            $goods->orderInfo->state = 4;
            $goods->orderInfo->save();
        });
        $this->success('申请成功，等待审核', ['order_sn' => $data['refund_sn']]);
    }

    public
    function modifyBackSn(OrderGoodsRefund2 $refund)
    {
        $refund_sn = $this->request->post('refund_sn');
        $back_sn = $this->request->post('back_sn');
        $order = $refund->where('refund_sn', $refund_sn)->find();
        if ($order->refund_type != 1) $this->error('该操作不合法');
        $order->back_sn = $back_sn;
        $order->save();
        $this->success('填写成功');
    }

    public
    function cancelRefund(OrderGoodsRefund2 $refund)
    {
        $refund_sn = $this->request->post('refund_sn');
        $order = $refund->where('refund_sn', $refund_sn)->find();
        if ($order->state != 0) $this->error('该操作不合法');
        $order->state = 3;
        $order->save();
        $this->success('撤销成功');
    }

    /**
     * @param Order $order
     * @param $page
     * @param $limit
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public
    function getRefundOrderList(OrderGoodsRefund2 $orderGoodsRefund, $page, $limit)
    {
        $list = $orderGoodsRefund
            ->page($page, $limit)
            ->order('id desc')
            ->select()
            ->each(function ($item) {
                $item['orderGoods'] = OrderGoods::where('id', $item['order_goods_id'])->find();
                $item['goods'] = Goods::where('id', $item['orderGoods']['goods_id'])->find();
                $item['orderInfo'] = Order::where('id', $item['orderGoods']['order_id'])->find();
                $item['images'] = full_array_url($item['images']);
                $item['goods']['slider_images'] = full_array_url($item['goods']['slider_images']);
                $item['goods']['content_images'] = full_array_url($item['goods']['content_images']);
                $item['orderGoods']['goods_image'] = full_url($item['orderGoods']['goods_image']);
                $item['state_txt'] = $this->getState($item['state']);
                return $item;
            });
        $this->success('', $list);
    }

    protected function getState($state)
    {
        $list = [
            0 => '待审核', 1 => '通过', 2 => '驳回', 3 => '用户取消',
        ];
        return $list[$state] ?? '';
    }

    public
    function getRefundOrder(OrderGoodsRefund2 $refund)
    {
        $refundSn = $this->request->get('refund_sn');
        $order = $refund
            ->with(['orderGoods'])
            ->where('refund_sn', $refundSn)
            ->find();
        $order['state_txt'] = $this->getState($order['state']);
        $this->success('', $order);
    }

    public
    function getOrder(Order $order)
    {
        $orderSn = $this->request->get('order_sn');
        $data = $order
            ->with(['orderGoods'])
            ->where('order_sn', $orderSn)
            ->find();
        $this->success('', $data);
    }

    /**
     * @param OilOrder $order
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public
    function getOilOrder(OilOrder $order)
    {
        $orderSn = $this->request->get('order_sn');
        $data = $order
            ->with(['refund', 'station'])
            ->where('order_sn', $orderSn)
            ->find();
        $this->success('', $data);
    }
}